[  Old Style Crackin' & Dongle  ]

Questo tutorial � rivolto a persone che hanno una discreta conoscenza del
linguaggio macchina, padronanza di un debugger sotto Win32 e ovviamente una
minima esperienza di reverse  engeneering.
Per seguire questo piccolo tutorial sono necessari almeno 2 tools, ossia un buon
debugger (io ho usato il debugger incorporato nel M$ Visual C++) e un Hex Editor
(io uso Hex Workshop, per il fix-up finale). L' Hex Editor in realt� vi servir�
per rendere definitiva la modifica e quindi non � strettamente necessario a
livello didattico. Non indispensabile ma molto utile si puo' rivelare un buon
disassemblatore, io consiglierei in questo caso il WDasm.
Ok, passiamo al crack vero e proprio.
Il programma target � ORCAD Capture 7.01, un ottimo CAD elettrico per la
realizzazione di circuiti elettronici, e come molti prg dello stesso genere
decisamente costoso. Insieme al prg viene fornita la chiave HW, e senza di essa
ORCAD Capture (ovviamente :) non parte.
Durante l'installazione del prodotto viene richiesto un S/N, se avete
l'originale tanto meglio, altrimenti metteteci un numero qualsiasi di 6 cifre e
installatelo da qke parte nell' HD.
La directory contenente il programma avr� al suo interno il file .EXE principale
e un po' di .DLL; come primo approccio tendenzialmente bisognerebbe aprire il
.EXE con il disassemblatore, soprattutto per farsi una idea di quali funzioni
vengono importate dal file eseguibile. WDasm in questi casi � un ottimo mezzo,
perch� sebbene meno potente � decisamente piu' immediato e veloce di altri
disassm tipo IDA. Ho detto all' inizio che il disassemblatore non era
necessario, ed infatti � cosi. Per il crack fine a se stesso non serve, la prima
volta che ho sprotetto ORCAD avevo solo il VC++ a disposizione (non ero a casa)
e al posto dell' Hex Editor ho fatto un prg in Turbo Pascal per il fix-up
finale. Cio' non toglie che in altri casi (moltissimi) e soprattutto per chi non
ha molta dimestichezza con il L.M. la soluzione di disassemblare l'eseguibile e
le .DLL da esso importate contestualmete al suo debugging non solo � utile per
risparmiare tempo, ma necessaria.
Aprite il debugger e caricate il programma eseguibile, nel Developer Studio
premete F11 (STEP  INTO) e vi troverete all'inizio del programma. Ecco un DUMP
della situazione :

006027B0 64 A1 00 00 00 00    mov         eax,fs:[00000000]
006027B6 55                   push        ebp
006027B7 8B EC                mov         ebp,esp
006027B9 6A FF                push        0FFh
.
.

Se le istruziono vi spaventano, scaricatevi il mio primo tutorial, leggetelo,
esercitatevi e riaprite questo tra un po' di tempo ;-)
Ok, ci siamo. Munitevi di carta e penna, perch� dovrete scrivervi qcosina qua e
la (poca roba tranky), e cominciamo.
Il comando di STEP OVER � F10, mentre per il RUN TO CURSOR � piu' semplice
posizionarsi sulla riga e premere il tasto destro del topo.
La mia prima regola � : FATTI UNA IDEA DI COME FUNZIONA IL PROGRAMMA. Puo'
sembrare stupido al giorno d'oggi quando ci sono toolz kome SoftICE mettersi a
tracciare a mano un prg, ma vi assicuro che non � cos�. Spesso crackare col
SoftICE equivale a usare il lanciafiamme per ammazzare una zanzara, quando
basterebbe un giornale arrotolato. SoftICE usatelo quando serve, laddove fallite
con altri toolz (per loro limiti, non per vostra incapacit�, altrimenti siamo
daccapo!).
Iniziamo con uno STEP OVER. Premete F10, noterete che all' indirizzo 00602888 l'
HD si mette in moto, senza che succeda nulla; prendete quaderno e penna e
annotatevelo, dovesse mai servire.
Il primo 'intoppo' lo troviamo a 006028A1 :

006028A1 46                   inc         esi
006028A2 8A 06                mov         al,byte ptr [esi]
006028A4 84 C0                test        al,al
006028A6 74 04                je          006028AC
006028A8 3C 22                cmp         al,22h
006028AA 75 F5                jne         006028A1
006028AC 80 3E 22             cmp         byte ptr [esi],22h
.
.

se continuiamo a premere F10 rimaniamo bloccati all'interno del ciclo. Una
rapida occhiata fa  subito vedere che la condizione di uscita � una sola perch�
sia 'je 006028AC' che l'istruzione 'jne 006028A1' fanno si che COMUNQUE il
programma continui dall' indirizzo 006028AC; sar� sufficiente quindi far
proseguire il programma fino alla istruzione a tale indirizzo posizionandovisi
sopra e selezionando dal menu' del tasto dx del mouse RUN TO CURSOR (con un
debugger a riga di comando come il DEBUG sarebbe 'G 006028AC'). Attenzione
perch� in altri casi all'interno del ciclo potrebbero trovarsi piu' istruzioni
di salto condizionato a locazioni differenti. In tali casi occorre studiare un
po' piu' attentamente il ciclo oppure se si � particolarmente pigri (io spesso)
andate a occhio e ne provate un po' a caso. Ho scoperto che statisticamente
faccio prima e sbaglio meno, credo sia frutto dell'esperienza e ne godo alquanto
;-)
Bene, se avete fatto tutto come doveva essere fatto ora il programma dovrebbe
essere in  attesa di eseguire l'istruzione  'cmp byte ptr [esi],22h', al che
possiamo continuare allegramente il notro tracing con F10, fino ad incontrare
l'indirizzo 006028ED. Vediamo cosa ha disassemblato per noi il debugger :

006028ED 8B 45 A8             mov         eax,dword ptr [ebp-58h]
006028F0 25 FF FF 00 00       and         eax,0FFFFh
006028F5 50                   push        eax
006028F6 56                   push        esi
006028F7 6A 00                push        0
006028F9 6A 00                push        0
006028FB FF 15 48 0B 6A 00    call        dword ptr ds:[6A0B48h]
.
.

mmhhh sembra proprio una chiamata sospetta, con 4 parametri pushati nello stack.
Arriviamo con F10 all'istruzione 'call        dword ptr ds:[6A0B48h]' ed
eseguiamola (Sempre F10) prima di decidere se valga o meno la pena di tracciarla
internamente. Non succede nulla.... Pero il valore del registro EAX, che
contiene certamente il valore di ritorno della call viene messo di nuovo nello
stack prima di un' altra call, ovvero :

00602901 50                   push        eax
00602902 E8 DD BA 01 00       call        0061E3E4
00602907 50                   push        eax
00602908 FF 15 8C 1C 6A 00    call        dword ptr ds:[6A1C8Ch]
0060290E EB 28                jmp         00602938
.
.

che a sua volta passa EAX di ritorno a quella successiva. Dato che non sappiamo
ancora nulla del programma, non ci resta altro da fare che eseguire tenendo a
mente (o scrivendo) tutte queste considerazioni. Procediamo ancora con F10 fino
ad eseguire la chiamata e *SORPRESA* ;)  il progamma parte. E' importante
cercare di capire a che 'livello' del programma ci si trova osservando come si
comporta la routine appena eseguita. Nel nostro caso 'call        0061E3E4' �
l'entrata principale del programma. Noterete infatti che dopo qke secondo di
'freeze' il programma visualizzer� una MessageBox dicendoci che (ma tu
guarda...) la chiave HW non c'� o � rotta (aspetta aspetta che ora la
aggiustiamo noi :P) dopodich� il programma si chiude, anche se formalmente il
debugger ci riporta all'istruzione successiva. Continuando a tracciare l'unico
risultato sarebbe di chiudere il programma del tutto.
E' evidente che 'call 0061E3E4' alla locazione 00602902 va esaminata
attentamente per cui restartiamo il programma (RESTART o CTRL+SHIFT+F5)e
stavolta possiamo dire al debugger di eseguire il programma fino alla locazione
incriminata 00602902, posizionandoci sopra con il cursore e premendo CTRL+F10
(RUN TO CURSOR) oppure per command line debuggers con 'G 00602902'.
Ora il programma sta per eseguire la chiamata, ma noi non vogliamo piu'
eseguirla, tanto sappiamo che cosa fa. Ci interessa tracciarla (STEP INTO) con
F11. Ci ritroveremo con il sotto mano la prima istruzione eseguita dalla call
ovvero :

0061E3E4 55                   push        ebp
0061E3E5 8B EC                mov         ebp,esp
0061E3E7 FF 74 24 14          push        dword ptr [esp+14h]
0061E3EB FF 75 10             push        dword ptr [ebp+10h]
0061E3EE FF 75 0C             push        dword ptr [ebp+0Ch]
0061E3F1 FF 75 08             push        dword ptr [ebp+8]
0061E3F4 E8 89 00 00 00       call        0061E482
0061E3F9 5D                   pop         ebp
0061E3FA C2 10 00             ret         10h
.
.

Per ora possiamo intuire poco di cosa fa la chiamata in 0061E3F4, ma ci vuole
poco per osservare che a) la chiamata � una standard call che usa variabili
locali b) non ci sono istruzioni di salto PRIMA dell'istruzione 'ret 10h' e
nemmeno un uso improprio dello stack per falsare l'istruzione di ret.
La cosa piu' ovvia da pensare � che la 'call 0061E482' si comporti esattamente
come nel caso della chiamata vista in precedenza all'indirizzo 00602902 e faccia
cio� partire il programma. Non resta che accertarsene!
Tracciamo il programma (F10) fino ad eseguirla e stiamo a vedere che succede.
Avevamo visto bene, questa call si comporta come la precedente, segnamoci
l'address 0061E482.  Ora abbiamo questa successione:    

                                     00602902
                                       |______\  0061E3F4
                                              /     |_______\  0061E482
                                                            /

Possiamo piazzare un bel breakpoint a 0x0061E482 e vedere che succede al
prossimo restart (ricordatevi di riattivare il breakpoint dopo aver restartato
il programma !); � il momento di restartare il prg (RESTART o CTRL+SHIFT+F5) e
settare il breakpoint o riattivarlo, tutto cio' nel menu Edit --> Breakpoints 
(ALT+F9) inserendo 'Break at : 0x0061E482' e clikkando OK.
Ora si puo' comodamente eseguire il programma con GO (F5) e ci troveremo proprio
:

0061E482 FF 25 E0 1A 6A 00    jmp         dword ptr ds:[6A1AE0h]
0061E488 CC                   int         3
.
.

non abbiamo scelta, dobbiamo eseguire il salto con F10 trovando stavolta :

7C42D26D 55                   push        ebp
7C42D26E 8B EC                mov         ebp,esp
7C42D270 53                   push        ebx
7C42D271 56                   push        esi
7C42D272 57                   push        edi
7C42D273 BE FF FF FF FF       mov         esi,0FFFFFFFFh
7C42D278 E8 D8 3D FF FF       call        7C421055
7C42D27D FF 75 14             push        dword ptr [ebp+14h]
7C42D280 FF 75 10             push        dword ptr [ebp+10h]
7C42D283 FF 75 0C             push        dword ptr [ebp+0Ch]
7C42D286 FF 75 08             push        dword ptr [ebp+8]
7C42D289 8B 78 04             mov         edi,dword ptr [eax+4]
7C42D28C E8 10 FC FF FF       call        7C42CEA1
.
.

direi che conviene a questo punto segnarsi l' EIP ovvero 7C42D26D in modo da
levare l'indirizzo del breakpoint precedente e sostituirlo appunto con
0x7C42D26D per evitare altre perdite di tempo.
A questo punto cominciamo ad essere abbastanza 'dentro' il programma, in ogni
caso dobbiamo esplorare anche questa nuova routine sempre con il nostro fido
F10.
L' istruzione alla locazione 7C42DA5  :

7C42D2A3 8B CF                mov         ecx,edi
7C42D2A5 FF 53 54             call        dword ptr [ebx+54h]
7C42D2A8 85 C0                test        eax,eax
7C42D2AA 74 07                je          7C42D2B3
7C42D2AC 8B CF                mov         ecx,edi
.
.

� un'altra chiamata che si comporta in tutto e per tutto come la precedente. 
Ora il livello di nesting delle routines �:
 
               00602902
                 |______\  0061E3F4
                        /     |_______\  0061E482
                                      /     |_______\  7C42D26D
                                                    /    |_______\  [ebx+54h]
                                                                 /

difatti per ora ignoriamo l'indirizzo a cui punta [ebx+54h] (d'accordo, potremmo
ricostruirlo, ma perch� sprecarci ? :-) ma � nostro compito scoprirlo : stiamo
infatti addentrandoci sempre piu' all'interno del programma e la routine di
check dovrebbe essere nei paraggi oramai.
Restartiamo (CTRL+SHIFT+F5) il prg e sostituiamo il breakpoint precedente con
quello appena trovato cio� 0x7C42D2A5 dopodich� eseguiamo il prg con F5 fino a
tale locazione. Tracciamo la call con F11 e ci troviamo in :

004F5910 64 A1 00 00 00 00    mov         eax,fs:[00000000]
004F5916 55                   push        ebp
004F5917 8B EC                mov         ebp,esp
004F5919 6A FF                push        0FFh
004F591B 68 1B 5D 4F 00       push        4F5D1Bh
004F5920 50                   push        eax
.
.

anche se lo sconforto sta per impadronirsi del nostro cervello, mai abbattersi,
altrimenti tantovale lasciar perdere il crackin'. Ogni volta (ogni) che metto le
mani su un prg trovo un ostacolo nuovo, se dovessi abbattermi ogni volta non
avrei nemmeno cominciato.
Tornando a ORCAD, indovinate? F10 per tracciare il programma! Eheheh comincerete
ad odiare anche lo scooter F10 Malaguti tra un po'...
Pero' stavolta ci siamo.
Tutto fila liscio fino a :

004F59A9 8B CA                mov         ecx,edx
004F59AB E8 80 84 07 00       call        0056DE30
.
.

dove viene creata la MDI principale e la splashform di presentazione di ORCAD!
Ma la cosa piu' interessante che dovreste notare subito � il TEMPO che ci vuole
per riavere il controllo  del debugger, ovvero pochissimo mentre la routine di
check della chiave HW dura qche secondo. Cio' significa che non � ancora stata
eseguita! Bene bene....
Continuiamo il nostro STEP OVER con F10 (sempre lui) aspettandoci da un momento
all' altro questo maledetto check; l' attesa dura poco poich� gi� a :

004F59EC E8 AF FB FA FF       call        004A55A0
004F59F1 85 C0                test        eax,eax
004F59F3 75 0F                jne         004F5A04
004F59F5 8B 55 F0             mov         edx,dword ptr [ebp-10h]
004F59F8 8B 8A E8 00 00 00    mov         ecx,dword ptr [edx+0E8h]
004F59FE 85 C9                test        ecx,ecx
004F5A00 74 D7                je          004F59D9
004F5A02 EB C2                jmp         004F59C6
004F5A04 E8 F7 B1 FA FF       call        004A0C00
.
.

accade il fattaccio. Dopo aver eseguito 'call  004A55A0' il debugger si blocca
in attesa della fine della chiamata, e nel progamma ORCAD dopo qualche secondo
spunta la MessageBox che come sempre ci ricorda che siamo dei malandrini e non
abbiamo le carte in regola per usare il programma. Credo che a questo punto non
valga nemmeno la pena di dire quanto sia sospetto quel 'test eax,eax'  seguito
da 'jne 004F5A04' ....
La prima cosa da fare per levarsi il dubbio � vedere cosa farebbe il programma e
invertire la condizione, in questo caso il registro EAX vale 0 , basta mettere
EAX=00000001 (fate visualizzare la finestrella dei registri e modificatelo) e
vedere cosa accade dando un GO (F5).
Yeppaaaaaa! **IL PROGRAMMA PARTE!** Ok, Ok, non � stato nulla di eccezionale, ma
ogni crack per semplice che sia da una piccola soddisfazione!
A questo punto verrebbe la tentazione (mi � venuta e puntualmente ho fatto cosi'
:-) di modificare l'eseguibile e rendere definitiva la modifica sostituendo a
'jne 004F5A04' un piu' utile 'jmp 004F5A04' ovvero modificando i bytes
all'interno dell' .EXE da ....750F.... a ....EB0F....  solo che il crack NON E'
ANCORA FINITO.
Se con mente fredda si testasse il programma ci si accorgerebbe che in realt� la
chiave HW viene cercata ad esempio anche immediatamente PRIMA DI SALVARE, e non
� bello lavorare su un progetto senza poterlo salvare.....
La prima cosa che verrebbe in mente � quella di cercare l'altra chiamata e fare
anche li' un bel jnz -> jmp ma cio' implicherebbe tracciare ancora il programma
o cercare di brekkare subito prima del save, per non parlare del fatto che non
sappiamo a priori quante altre call alla routine di check ci possano essere.
Una strada molto piu' elegante e che mette al riparo anche da altri eventuali
check sparsi nel programma � quella di modificare la call che verifica la
presenza della chiave in modo che restituisca sempre EAX diverso da 0 evitandoci
la noia di cercare i punti nel programma in cui essa viene chiamata. L'ultimo
'sforzo' � quindi quello di tracciare anche la call di check e vedere come
modificarla per asservirla ai nostri biechi scopi.
Cancelliamo il vecchio breakpoint e settiamo quello nuovo all'istruzione di call
vista in precedenza (vedi dump sopra) ovvero a 0x004F59EC e diamo nuovamente GO
(F5). Entriamo nella chiamata con F11 e diamo una occhiata in giro :

004A55A0 64 A1 00 00 00 00    mov         eax,fs:[00000000]
004A55A6 55                   push        ebp
004A55A7 8B EC                mov         ebp,esp
004A55A9 6A FF                push        0FFh
004A55AB 68 0B 59 4A 00       push        4A590Bh
004A55B0 50                   push        eax
004A55B1 64 89 25 00 00 00 00 mov         dword ptr fs:[0],esp
004A55B8 83 EC 7C             sub         esp,7Ch
004A55BB 8D 4D F0             lea         ecx,dword ptr [ebp-10h]
004A55BE 53                   push        ebx
004A55BF 56                   push        esi
004A55C0 57                   push        edi
004A55C1 BE D8 A6 62 00       mov         esi,62A6D8h
004A55C6 E8 33 BA 15 00       call        00600FFE
.
.

a prima vista nulla di particolare, senonch� dato il fatto che la call
restituisce in EAX il risultato e si preoccupa pure di visualizzare una
MessageBox, potremmo essere cosi' fortunati  da essere talmente addentro il
programma da aver beccato la routine di check che oltre a fare la verifica non
fa null'altro. Se cosi' fosse la soluzione sarebbe di sostituire le prime
istruzioni della call con un 'mov eax,00000001'  dopodich� 'ret'  ed il gioco
sarebbe fatto. Altrimenti la sostituzione o l'alterazione andrebbe fatta subito
PRIMA del 'ret' vero e proprio dopo che la routine ha eseguito i suoi compiti.
Vi dico gi� che oggi siamo stati fortunati ;-) per cui ci andr� bene al primo
tentativo. Aprite il vostro Hex Editor e caricate il file CAPTURE.EXE. Dovrete
sostituire i bytes che rappresentano l' istruzione
         
004A55A0 64 A1 00 00 00 00    mov         eax,fs:[00000000]
         ^^^^^^bytes^^^^^^

con altri bytes in modo da farla diventare :

004A55A0 B8 01 00 00 00       mov         eax,00000001
004A55A5 C3                   ret

Voglio solo ricordare (vedi tutorial precedente) che i bytes possono solo essere
SOSTITUITI e non AGGIUNTI o CANCELLATI, per cui bisogna stare attenti a NON
SPEZZARE LE ISTRUZIONI, al limite aggiungendo dei NOP (90h) o se manca spazio a
reinventare per cos� dire il codice in modo da farcelo stare.
Tornando all' Hex Editor, mettete come stringa di ricerca esadecimale i bytes
che rappresentano il codice originale, almeno 10 bytes in modo da non trovare
troppe volte la stringa. Ad esempio in questo caso potete segnare
'558BEC6AFF680B59' e una volta trovati accertarvi che anche i bytes prima e dopo
coincidano. Nel nostro caso la sequenza compare una volta sola e quindi non c'�
dubbio che sia proprio il pezzo di programma da modificare; altre volte puo'
rendersi necessario controllare piu' bytes, in ogni caso una volta trovata la
sequenza dobbiamo risalire ai bytes da modificare, che qui sono i 6 bytes
precedenti. Dobbiamo modificare i bytes all' offset 000A49A0 da '64A100000000'
in 'B801000000C3' e salvare il file  magari come CAPTURE2.EXE. Fatto ?
Chiudete l' Hex Editor (non serve piu' ;-) e lanciate CAPTURE2.EXE.
Oh gioia oh gaudio, Va! E non dirmi che...... SALVA! Ehheheh e come dubitare? :P
E questo � quanto per ORCAD Capture 7.0 with Dongle (Sentinel per l'esattezza).
Alcune note :

1) Non sempre con i debuggers 'tradizionali' si riesce a tracciare con efficacia
un programma, ma vale *SEMPRE* la pena di farlo come prima cosa, anche per farsi
un'idea del programma.

2) Una volta scoperto che la routine di check era all'indirizzo 004A55A0 avremmo
potuto caricare il programma in un  disassemblatore, andare a tale indirizzo e
vedere da quali indirizzi la chiamata veniva referenziata (chiamata) per
modificare li' i  jnz --> jmp, e nel caso specifico di ORCAD erano 7 tra cui il
nostro 004F59EC. Molto piu' elegante e sicuro modificare quindi la call stessa
che non le procedure chiamanti, anche se in altri casi se tutto funziona
eliminando un jnz (verificate sempre pero'!) puo' bastare. Beh, noi ora abbiamo
anche eliminato il tempo di attesa per il dongle check, in un certo senso those
guys at ORCAD dovrebbero ringraziarci bwhahahah ;-)

3) Un altro motivo per cui si dovrebbe cercare di non usare i disassemblatori �
perch� se il file � compresso il disassemblatore serve a una sega :-) a meno di
non riuscire a spakkettare l' .EXE. Tuttavia dove possibile aprite il
disassemblatore parallelamente al debugger, � sempre un utile aiuto.

4) Se il file � compresso (o crittato) e non si riesce ad applicare il patch
finale, sono kazzetti amari. Sotto DOS utilizzavo un piccolo launcher che
hokkava l' INT 08h, lanciava il prg target e verificava che si fosse
scompattato/decrittato dopodich� cercava i bytes e applicava il patch. Era
scritto in TP pero' andava benone. Purtroppo sotto Win32 non so ancora come
realizzare un programma analogo, per ora accontentatevi di quello che ha fatto
StonE in ASM che lancia il prg incriminato e invece di hokkare un INT o una API
si segna l' Handle di processo, aspetta un tot e poi cerca nella memoria di tale
processo la sequenza da patchare sostituendola.

5) Se il file non � compresso ma non trovate comunque la sequenza, potrebbe
essere contenuta in una .DLL dinamica, percio' prima di spaccare il PC cercate
in tutte le .DLL (anche in quelle che i cazzo di programmini di Setup infilano
nella directory \windows\system).

6) non esistono crack impossibili, � solo questione di tempo e di palle.


(C) 1999 T3X  for RingZer0
  _________        ____  ___                                                    
  ########@ a##gg  \##B ,##M                                                    
  ########@,#####@  M##C&##"   <------------------------=< [ EFnet or IRCnet ]           
     ##@   &#" Q##  `#####N                                                     
     ##@       Q#B   7###B    GReEtZ GoEs oUt To : SoftPJ per lo spazio nel BfI       
     ##@      g#B"    ###C      e a tutti i D4RkSiDErz per le kose ke abbiamo
     ##@      ###@   ,###@      saputo fare, ai bros M|kky, Layne, Slay, Hija,
     ##@       \##a  &####a     GOLD, a Maddevil, R4|k3r Net-Call e tutti gli
     ##@   ##  ]##L /##@##W        altri ke non ho voglia di menzionare :-)         
     ##@   Q#g_d##  @##"Q##g                                                    
     ##@   `####B" Z##N `##B,                                                   
            `"""                
      E' assolutamente VIETATO riprodurre questo testo usando fusilli 
  Barilla per comporre le lettere nonch� utilizzare le informazioni quivi 
         contenute per fare colpo sulla compagna di banco strafiga 
                            (tanto non funziona).